package com.bdqn.design.proxy.cglib;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * IntermediaryMethodInterceptor
 *
 * @author LILIBO
 * @since 2023-10-10
 */
public class IntermediaryMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        // ⑤ 环绕增强 在目标方法执行前后都可以执行的横切逻辑。环绕增强可以完全控制目标方法的执行过程，可以选择是否调用目标方法以及何时调用
        return around(proxy, method, args, methodProxy);
    }

    /**
     * 环绕增强
     *
     * @param proxy
     * @param method
     * @param args
     * @param methodProxy
     * @return
     */
    private Object around(Object proxy, Method method, Object[] args, MethodProxy methodProxy) {
        // ① 前置增强 在目标方法执行之前执行的横切逻辑。可以用于执行一些预处理操作，如参数验证、权限检查等
        before(proxy, method, args);
        Object feedback = null;
        try {
            // 通过反射执行目标对象的实际业务
            feedback = methodProxy.invokeSuper(proxy, args);
        } catch (Throwable e) {
            // ③ 异常增强 在目标方法抛出异常时执行的横切逻辑。可以用于处理异常、发送通知等
            error(e);
        } finally {
            // ④ 最终增强 它在目标方法执行结束后（无论是否发生异常）都会执行。最终增强通常用于资源清理或日志记录等必须执行的操作
            finallys();
        }

        // ② 后置增强 在目标方法执行之后执行的横切逻辑。可以用于执行一些清理操作，如资源释放、日志记录等
        after(feedback);
        return feedback;
    }

    /**
     * 最终增强
     */
    private void finallys() {

    }

    /**
     * 异常增强
     *
     * @param e
     */
    private void error(Throwable e) {

    }

    /**
     * 前置增强
     */
    private void before(Object proxy, Method method, Object[] args) {
        System.out.println("提供看房前服务");
    }

    /**
     * 后置增强
     */
    private void after(Object feedback) {
        System.out.println("提供看房后服务");
    }

}
